package cn.xerllent.quartz.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.xerllent.common.exception.BadRequestException;
import cn.xerllent.common.service.impl.BaseServiceImpl;
import cn.xerllent.common.utils.FileUtil;
import cn.xerllent.quartz.entity.QuartzJob;
import cn.xerllent.quartz.service.QuartzJobService;
import cn.xerllent.quartz.service.mapper.QuartzJobMapper;
import cn.xerllent.quartz.utils.QuartzManage;
import lombok.AllArgsConstructor;

// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;

@Service
//@CacheConfig(cacheNames = "quartzJob")
//@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class QuartzJobServiceImpl extends BaseServiceImpl<QuartzJobMapper, QuartzJob> implements QuartzJobService {

	@Resource
    private QuartzManage quartzManage;

    @Override
    //@Cacheable
    public Map<String, Object> queryAll(QuartzJob filter, Pageable pageable) {
		pageHelper(pageable);
        PageInfo<QuartzJob> page = new PageInfo<>(queryAll(filter));
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("list", page.getList());
        map.put("total", page.getTotal());
        return map;
    }


    @Override
    //@Cacheable
    public List<QuartzJob> queryAll(QuartzJob filter) {
    	//方法1
    	QueryWrapper<QuartzJob> querywrapper = new QueryWrapper<>();
    	if(ObjectUtil.isNotEmpty(filter)) {
        	if(StringUtils.isNotBlank(filter.getName())) {
        		querywrapper.and(w->
        		w.like("name", filter.getName()).or()
        		.like("bean", filter.getName()).or()
        		.like("comment", filter.getName())
				);
        	}
        	if(filter.getEnabled()!=null) {
        		querywrapper.eq("enabled", filter.getEnabled());
        	}
    	}
    	return this.list(querywrapper);
    }


    @Override
    public void download(List<QuartzJob> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (QuartzJob quartzJob : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("id", quartzJob.getId());
            map.put("任务名称", quartzJob.getName());
            map.put("任务执行类名", quartzJob.getBean());
            map.put("cron表达式", quartzJob.getCron());
            map.put("状态", quartzJob.getEnabled());
            map.put("参数", quartzJob.getParams());
            map.put("备注", quartzJob.getComment());
            map.put("创建日期", quartzJob.getCreatetime().toString());
            map.put("修改日期", quartzJob.getUpdatetime().toString());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    /**
     * 更改定时任务状态
     *
     * @param quartzJob /
     */
    @Override
    public void toggleEnabled(QuartzJob quartzJob) {
        if (quartzJob.getEnabled()) {
        	quartzManage.pauseJob(quartzJob);
        } else {
        	quartzManage.resumeJob(quartzJob);
        }
        quartzJob.setEnabled(!quartzJob.getEnabled());
        this.saveOrUpdate(quartzJob);
    }

    @Override
    public boolean save(QuartzJob quartzJob) {
    	//1测试会抛出异常
    	quartzManage.testJob(quartzJob);
    	//2保存到数据库
    	boolean flag = retBool(baseMapper.insert(quartzJob));
        //3添加到任务执行环境
        quartzManage.addJob(quartzJob);
        return flag;
    }

    /**
     * 已经存在的quartzJob的bean类名不能更改
     * */
    @Override
    public boolean updateById(QuartzJob quartzJob) {
    	//1测试会抛出异常
    	quartzManage.testJob(quartzJob);
    	//2保存到数据库
    	boolean flag = retBool(baseMapper.updateById(quartzJob));
    	//3任务重新执行
        quartzManage.updateJobCron(quartzJob);
        return flag;
    }

    /**
     * 立即执行定时任务
     * @param quartzJob /
     */
    @Override
    public void execution(QuartzJob quartzJob) {
        quartzManage.runJobNow(quartzJob);
    }

    /**
     * 查询启用的任务
     * @return List
     */
    @Override
    public List<QuartzJob> findByEnabled() {
    	QueryWrapper<QuartzJob> querywrapper = new QueryWrapper<>();
    	querywrapper.eq("enabled", true);
        return baseMapper.selectList(querywrapper);
    }

    @Override
    public void removeByIds(List<Integer> idList) {
        idList.forEach(id -> {
            QuartzJob quartzJob = baseMapper.selectById(id);
            quartzManage.deleteJob(quartzJob);
        });
        baseMapper.deleteBatchIds(idList);
    }
    
    /**
     * job的日志类型接口
     * */
    @Override
    public int getLogtype(Integer id) {
    	QuartzJob quartzJob = getById(id);
        int logtype;
		try {
			logtype = (int)BeanUtil.getFieldValue(Class.forName(quartzJob.getBean()).newInstance(), "logtype");
		} catch (Exception e) {
			 throw new BadRequestException("日志类型logtype获取失败："+e.getMessage());
		}
        return logtype;
    }
}
